package i18n

import (
	"errors"
	"fmt"
	"slices"
	"strconv"
	"strings"
)

type PluralMessage struct {
	Index uint8         // 参数索引位置，Count参数在T函数附加格式化参数中的索引位置, 例如 [1] 表示第1个参数为Count参数，从1开始计数
	Texts []*PluralText // 复数表达式文本列表，按从低到高进行规则匹配
}
type PluralText struct {
	Rules    []*CompareRule
	HasCount bool   // Text 文本中是否含有Count变量的占位符，如不含有则会将args中的Count参数剔除后再对Text行格式化输出
	Text     string // Text 复数翻译文本
}

type CompareRule struct {
	// CompareType 比较符号(16) "=", "<", "<=", ">", ">=", "!=", "[", "![", "%D=", "%D!=", "%D<", "%D<=", "%D>", "%D>=", "%D[", "%D!["
	CompareType CompareType
	// CompareVals 比较值：Count和这一个值进行比较, 最少有一个值, 取模或列表有多个值
	CompareVals CompareVals
}

func (c CompareRule) String() string {
	if strings.HasPrefix(c.CompareType.String(), "%D") { // 取模比较
		// 需要把%D 替换为CompareVals中发第1个数值
		switch c.CompareType.String() {
		case "%D[", "%D![":
			return fmt.Sprintf("%s%s]",
				strings.Replace(c.CompareType.String(), "D", strconv.Itoa(c.CompareVals[0]), 1),
				c.CompareVals.StringWithNotFirst())
		default:
			return fmt.Sprintf("%s%s",
				strings.Replace(c.CompareType.String(), "D", strconv.Itoa(c.CompareVals[0]), 1),
				c.CompareVals.StringWithNotFirst())
		}
	}
	switch c.CompareType.String() {
	case "[", "![":
		return fmt.Sprintf("%s%s]",
			c.CompareType.String(),
			c.CompareVals.String())
	default:
		return c.CompareType.String() + c.CompareVals.String()
	}

}

type CompareVals []int

func (c CompareVals) Len() int {
	return len(c)
}
func (c CompareVals) String() string {
	var s strings.Builder
	// int slice 转 string 切片字符串拼接，例如：[1, 2] => "1, 2"
	for i, v := range c {
		if i > 0 {
			s.WriteString(", ")
		}
		s.WriteString(strconv.Itoa(v))
	}
	return s.String()
}
func (c CompareVals) StringWithNotFirst() string {
	var s strings.Builder
	// int slice 转 string 切片字符串拼接，例如：[1, 2] => "1, 2"
	for i, v := range c {
		if i == 0 {
			continue
		}
		if i > 1 {
			s.WriteString(", ")
		}
		s.WriteString(strconv.Itoa(v))
	}
	return s.String()
}

type CompareType uint8

const (
	CompareTypeEqual             CompareType = iota + 1 // =    Count 等于
	CompareTypeLess                                     // <    Count 小于
	CompareTypeLessOrEqual                              // <=   Count 小于等于
	CompareTypeGreater                                  // > 	  Count 大于
	CompareTypeGreaterOrEqual                           // >=   Count 大于等于
	CompareTypeNotEqual                                 // !=   Count 不等于
	CompareTypeInList                                   // [    Count 在列表中
	CompareTypeNotInList                                // ![   Count 不在列表中
	CompareTypeModEqual                                 // %D=  Count % D 取模后等于
	CompareTypeModNotEqual                              // %D!= Count % D 取模后不等于
	CompareTypeModLess                                  // %D<  Count % D 取模后小于
	CompareTypeModLessOrEqual                           // %D<= Count % D 取模后小于等于
	CompareTypeModGreater                               // %D>  Count % D 取模后大于
	CompareTypeModGreaterOrEqual                        // %D>= Count % D 取模后大于等于
	CompareTypeModInList                                // %D[  Count % D 取模后在列表中
	CompareTypeModNotInList                             // %D![ Count % D 取模后不在列表中
)

func ParseCompareType(compareStr string) (CompareType, bool) {
	switch compareStr {
	case "=", "==":
		return CompareTypeEqual, true
	case "<":
		return CompareTypeLess, true
	case "<=":
		return CompareTypeLessOrEqual, true
	case ">":
		return CompareTypeGreater, true
	case ">=":
		return CompareTypeGreaterOrEqual, true
	case "!=":
		return CompareTypeNotEqual, true
	case "[":
		return CompareTypeInList, true
	case "![":
		return CompareTypeNotInList, true
	case "%D=", "%D==":
		return CompareTypeModEqual, true
	case "%D!=":
		return CompareTypeModNotEqual, true
	case "%D<":
		return CompareTypeModLess, true
	case "%D<=":
		return CompareTypeModLessOrEqual, true
	case "%D>":
		return CompareTypeModGreater, true
	case "%D>=":
		return CompareTypeModGreaterOrEqual, true
	case "%D[":
		return CompareTypeModInList, true
	case "%D![":
		return CompareTypeModNotInList, true
	default:
		return 0, false
	}
}
func (c CompareType) String() string {
	switch c {
	case CompareTypeEqual:
		return "="
	case CompareTypeLess:
		return "<"
	case CompareTypeLessOrEqual:
		return "<="
	case CompareTypeGreater:
		return ">"
	case CompareTypeGreaterOrEqual:
		return ">="
	case CompareTypeNotEqual:
		return "!="
	case CompareTypeInList:
		return "["
	case CompareTypeNotInList:
		return "!["
	case CompareTypeModEqual:
		return "%D="
	case CompareTypeModNotEqual:
		return "%D!="
	case CompareTypeModLess:
		return "%D<"
	case CompareTypeModLessOrEqual:
		return "%D<="
	case CompareTypeModGreater:
		return "%D>"
	case CompareTypeModGreaterOrEqual:
		return "%D>="
	case CompareTypeModInList:
		return "%D["
	case CompareTypeModNotInList:
		return "%D!["
	default:
		return ""
	}
}

// NewPluralMessage 创建复数消息对象，如果解析失败则返回错误
//   - rules := [][]string{ {`countRule`,`msgText`}... }
//   - JSON 格式示例1: [["N1:<1", "has no item"],["N1:=1", "has one item"], ["Y1:>1", "has %d items"]]
//   - JSON 格式示例2: [["N2:<1", "%s has no item"],["N2:=1", "%s has one item"], ["Y2:>1", "%s has %d items"]]

func NewPluralMessage(rules [][]string) (*Message, error) {
	if pluralMessage, err := ParsePluralMessage(rules); err == nil {
		return &Message{Plural: pluralMessage}, nil
	} else {
		return nil, err
	}
}

// MustPluralMessage 必须创建复数消息对象，如果解析失败则panic错误
//   - rules := [][]string{ {`countRule`,`msgText`}... }
//   - JSON 格式示例1: [["N1:<1", "has no item"],["N1:=1", "has one item"], ["Y1:>1", "has %d items"]]
//   - JSON 格式示例2: [["N2:<1", "%s has no item"],["N2:=1", "%s has one item"], ["Y2:>1", "%s has %d items"]]
func MustPluralMessage(rules [][]string) *Message {
	if pluralMessage, err := ParsePluralMessage(rules); err == nil {
		return &Message{Plural: pluralMessage}
	} else {
		panic("MustPluralMessage: " + err.Error())
	}
}

// Display 格式化显示复数消息翻译文本
//   - 依据Index索引位置从args中获取Count参数值
//   - 然后与复数表达式列表中的CompareVal进行比较，匹配则返回格式化后的翻译文本
//   - 如果未匹配到任何复数表达式，则返回空字符串
//   - 对于复数消息, 支持fmt格式化占位符, 如消息文本无自定义格式化占位符, 但T函数传递了多余的附加参数，则直接丢弃多余的参数
func (p *PluralMessage) Display(args ...any) string {
	if p == nil || len(args) < 1 || p.Index < 1 || p.Index > uint8(len(args)) {
		return ""
	}
	// 获取Count参数值
	count, ok := getIndexArgsCount(p.Index, args...)
	if !ok {
		// 无法获取Count参数值
		return ""
	}
	for _, text := range p.Texts {
		// 比较Count参数值是否匹配复数表达式
		matched := true
		for _, cmp := range text.Rules {
			if !p.compareCount(count, cmp.CompareVals, cmp.CompareType) {
				// 未匹配到复数表达式，则继续下一个文本比较
				matched = false
				break
			}
		}
		if !matched {
			continue
		}
		// 统计格式化参数个数是否匹配
		formatCount := getFormatArgsCount(text.Text)
		// 这里与简单消息的处理方式不同
		// 无自定义格式化占位符, 但是有附加参数, 则忽略参数，直接输出
		if formatCount == 0 {
			return text.Text
		}
		if !text.HasCount {
			// 未包含则需要将args中的Count参数剔除，否则会导致格式化参数个数不匹配
			if p.Index > 1 {
				args = append(args[:p.Index-1], args[p.Index:]...)
			} else {
				args = args[p.Index:]
			}
		}
		if len(args) > formatCount {
			// 参数过多，则需要剔除多余的参数，否则会导致格式化参数个数不匹配
			args = args[:formatCount]
		} else if len(args) < formatCount {
			// 占位符个数超出参数个数，则需要往args中的填充any{nil}参数，否则会导致格式化参数个数不匹配
			args = append(args, make([]any, formatCount-len(args))...)
		}
		return fmt.Sprintf(text.Text, args...)
	}
	return ""
}
func (p *PluralMessage) compareCount(count int, compareVal []int, compareType CompareType) bool {
	switch compareType {
	case CompareTypeEqual:
		return count == compareVal[0]
	case CompareTypeLess:
		return count < compareVal[0]
	case CompareTypeLessOrEqual:
		return count <= compareVal[0]
	case CompareTypeGreater:
		return count > compareVal[0]
	case CompareTypeGreaterOrEqual:
		return count >= compareVal[0]
	case CompareTypeNotEqual:
		return count != compareVal[0]
	case CompareTypeInList:
		return slices.Contains(compareVal, count)
	case CompareTypeNotInList:
		return !slices.Contains(compareVal, count)
	case CompareTypeModEqual:
		return count%compareVal[0] == compareVal[1]
	case CompareTypeModNotEqual:
		return count%compareVal[0] != compareVal[1]
	case CompareTypeModLess:
		return count%compareVal[0] < compareVal[1]
	case CompareTypeModLessOrEqual:
		return count%compareVal[0] <= compareVal[1]
	case CompareTypeModGreater:
		return count%compareVal[0] > compareVal[1]
	case CompareTypeModGreaterOrEqual:
		return count%compareVal[0] >= compareVal[1]
	case CompareTypeModInList:
		return slices.Contains(compareVal[1:], count%compareVal[0])
	case CompareTypeModNotInList:
		return !slices.Contains(compareVal[1:], count%compareVal[0])
	default:
		return false
	}
}

// ToStringSlices 获取字符串切片配置化结构，通常用于TOML/YAML/JSON序列化/反序列化
func (p *PluralMessage) ToStringSlices() [][]string {
	data := make([][]string, len(p.Texts))
	var rule strings.Builder
	for i, text := range p.Texts {
		if rule.Len() > 0 {
			rule.Reset()
		}
		if text.HasCount {
			rule.WriteString(fmt.Sprintf("Y%d:", p.Index))
		} else {
			rule.WriteString(fmt.Sprintf("N%d:", p.Index))
		}
		for i, compare := range text.Rules {
			if i > 0 {
				rule.WriteRune(';')
			}
			rule.WriteString(compare.String())
		}
		data[i] = []string{
			rule.String(),
			text.Text,
		}
	}
	return data
}

// Clone 复制复数消息表达式
func (p *PluralMessage) Clone() *PluralMessage {
	if p == nil {
		return nil
	}
	clone := new(PluralMessage)
	for _, text := range p.Texts {
		clone.Texts = append(clone.Texts, &PluralText{
			HasCount: text.HasCount,
			Rules:    text.Rules,
			Text:     text.Text,
		})
	}
	clone.Index = p.Index
	return clone
}

// ParsePluralMessage 格式化及检查校验复数消息表达式
//   - rules := [][]string{ {`countRule`,`msgText`}... }
//   - JSON 格式示例1: [["N1:<1", "has no item"],["N1:=1", "has one item"], ["Y1:>1", "has %d items"]]
//   - JSON 格式示例2: [["N2:<1", "%s has no item"],["N2:=1", "%s has one item"], ["Y2:>1", "%s has %d items"]]
func ParsePluralMessage(rules [][]string) (*PluralMessage, error) {
	if rules == nil {
		return nil, ErrParseMessageInvalidPlural
	}
	if len(rules) < 1 {
		return nil, ErrParseMessageEmptyPlural
	}
	pluraler := new(PluralMessage)
	for _, val := range rules {
		if len(val) != 2 {
			return nil, fmt.Errorf("ParsePlural: every plural text must be defined by [2]string{`countRule`,`msgText`}")
		}
		if val[0] == "" {
			return nil, errors.New("ParsePlural: rule(``) is empty")
		}
		if val[1] == "" {
			return nil, fmt.Errorf("ParsePlural: rule(%s) value is empty", val[0])
		}
		rules, index, hasCount, err := ParsePluralRule(val[0])
		if err != nil {
			return nil, err
		}
		if pluraler.Index < 1 {
			pluraler.Index = uint8(index)
		} else if pluraler.Index != uint8(index) {
			return nil, errors.New("ParsePlural: all rules must have same index")
		}
		pText := new(PluralText)
		pText.Text = val[1]
		pText.HasCount = hasCount
		pText.Rules = rules
		pluraler.Texts = append(pluraler.Texts, pText)
	}
	if len(pluraler.Texts) < 1 {
		return nil, ErrParseMessageEmptyPlural
	}

	return pluraler, nil
}

var (
	ErrRuleParserNonASCII         = errors.New("ruleParser: rule contains Non-ASCII character")
	ErrRuleParserEmpty            = errors.New("ruleParser: rule is empty")
	ErrRuleParserInvalidLength    = errors.New("ruleParser: rule length is invalid, min length is 5")
	ErrRuleParserInvalidHasCount  = errors.New("ruleParser: invalid rule.HasCount, must start with 'Y/N'")
	ErrRuleParserInvalidIndex     = errors.New("ruleParser: invalid rule.Index, must be greater than 0")
	ErrRuleParserInvalidSeparator = errors.New("ruleParser: invalid rule.Separator, must start with ':'")
	ErrRuleParserInvalidType      = func(s string) error {
		return fmt.Errorf("ruleParser: invalid rule.Type: %s", s)
	}
	ErrRuleParserInvalidValue = func(s string) error {
		return fmt.Errorf("ruleParser: invalid rule.Value: %s", s)
	}
)

// ParsePluralRule 解析复数文本规则表达式
//   - countRule 格式为 " BI : CompareType + CompareVal; CompareType + CompareVal... "
//   - countRule 规则由半角字符(ASCII字符)定义, 包含的空白字符及非ASCII字符将被忽略
//   - `B` 是一个用 `Y`或`N` 表示的布尔值, 其含义是 msgText 中是否包含有显示Count参数对应的"%d"占位符
//   - `B` 为 `Y` 时表示 msgText 中有Count参数对应的"%d"占位符，则会保留T函数 args... 中的Count参数进行格式化输出
//   - `B` 为 `N` 时即不包含，则会将T函数附加 args... 参数中的Count参数剔除后再对Text行格式化输出
//   - `I` 是一个正整数, 表示Count参数在T函数 args... 参数中的索引位置, 从1开始计数, 同一Key下的全部复数文本规则的Count参数的索引值必须一致
//   - `I` 为 `1` 如: Y1 表示Count参数在T函数 args... 参数中的第1个位置, 即第1个参数为Count参数
//   - `I` 为 `2` 如: Y2 表示Count参数在T函数 args... 参数中的第2个位置, 即第2个参数为Count参数
//   - `CompareType` 表示比较类型, 如 ">", "<", "=", "!=", "%" 等16种比较类型
//   - `CompareVal` 表示比较值, 如 "0","1", "2", "-100" 等整数值
//   - 示例:
//   - " N1:<1 "  表示当Count参数小于1时使用该文本, 且 msgText 不包含Count:"%d"占位符, 如 "has no item"
//   - " N1:=1 "  表示当Count参数等于1时使用该文本, 且 msgText 不包含Count:"%d"占位符, 如 "has one item"
//   - " Y1:>2 "  表示当Count参数大于2时使用该文本, 且 msgText 包含Count:"%d"占位符, 如 "has %d items"
//   - 支持取模后比较 %
//   - " Y1:%2=1 " 表示 Count % 2 取模后等于1时使用该文本
//   - " N1:%10=[1,2,3] " 表示当 Count % 10 取模后 [1,2,3] 清单中时使用该文本
//   - 支持清单比较: [1,2,3], ![1,2,3]
//   - " N1:[1,2,3] "  表示当Count参数在[1,2,3]清单中时使用该文本
//   - " N1:![1,2,3] " 表示当Count参数不在[1,2,3]清单中时使用该文本
//   - 支持AND并联多个比较条件 ( 用分号分隔 ) 如 "N1:>=1;<3" 表示大于等于1且小于3
//   - " N1:>1; <3 " 表示当 Count参数 大于1且小于3时使用该文本
//   - " Y1:>1; <30; %10=1 " 表示当 Count 参数大于1且小于30, 且 Count % 10 取模后等于1时使用该文本
//   - " Y1:>=10; <=100; %10=1 " 表示当 Count 参数大于等于10且小于等于100, 且 Count % 10 取模后等于1时使用该文本
//   - " Y1:>100; %100[1,2,3] " 表示当 Count 参数大于100, 且 Count % 100 取模后在 [1,2,3] 清单中时使用该文本
func ParsePluralRule(rule string) (rules []*CompareRule, index int, hasCount bool, err error) {
	// ----------------------------------------------------------
	// 注意：处于性能考量, ParsePluralRule 不允许做拆分设计或封装设计
	// ----------------------------------------------------------
	// 上一版本，通过Rune/Buffer切片处理, 封装为一个通用的池化对象
	// Bench测试结果，CPU/内存占用很低, GC 16, 性能不理想
	// ----------------------------------------------------------
	// i18n 包加载语言文件时，仅进行一次复数文本规则表达式的解析
	// 由此考量，进行极简化处理, 抽离原 parsingRule 对象为一个函数，直接使用Byte切片处理、遍历和解析
	// 这一版本，通过Byte切片化处理, 不使用正则表达式
	// Bench测试结果, CPU/内存占用低, GC 4, 性能大幅提升
	if len(rule) == 0 {
		return nil, 0, false, ErrRuleParserEmpty
	}
	// 过滤 rule 中空白字符和非ASCII字符以及多余的分隔符号
	data := make([]byte, 0, len(rule))
	isSplitA, isSplitB := false, false
	ruleCount := 0
	for _, c := range rule {
		switch c {
		case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
			continue
		case ':':
			if isSplitA {
				continue
			}
			isSplitA = true
			data = append(data, byte(c))
		case ';':
			if isSplitB {
				continue
			}
			ruleCount++
			isSplitB = true
			data = append(data, byte(c))
		default:
			if c >= 0x80 {
				continue
			}
			isSplitB = false
			data = append(data, byte(c))
		}
	}
	if len(data) > 0 && data[len(data)-1] == ';' {
		data = data[:len(data)-1]
	}
	if len(rule) < 5 {
		return nil, 0, false, ErrRuleParserInvalidLength
	}
	// 验证首个字符是否为 'Y' 或 'N', 提取 hasCount 布尔值
	switch data[0] {
	case 'N', 'n':
		hasCount = false
	case 'Y', 'y':
		hasCount = true
	default:
		return nil, 0, false, ErrRuleParserInvalidHasCount
	}
	data = data[1:]
	i, j := 0, 0
	// 验证索引是否合法：索引必须大于0
	for i < len(data) && data[i] >= '0' && data[i] <= '9' {
		i++
	}
	if i == 0 {
		return nil, 0, false, ErrRuleParserInvalidIndex
	}
	index, err = strconv.Atoi(bytesToString(data[:i]))
	if index < 1 || err != nil {
		return nil, 0, false, ErrRuleParserInvalidIndex
	}
	// 验证分隔符
	// 规则必须以 ':' 开头
	if i >= len(data) || data[i] != ':' {
		return nil, index, hasCount, ErrRuleParserInvalidSeparator
	}
	// 裁去左侧已解析的字符
	data = data[i+1:]
	// 最简单一条规则至少需要2个字符，例如：>1
	if len(data) < 2 {
		return nil, index, hasCount, ErrRuleParserEmpty
	}
	// 开始解析规则
	// 统计全部rules表达式数量，建立符合容量的rules切片, 避免扩容
	// 当局部变量被分配在堆上时，函数返回的切片(指针)是安全的。
	// 例如，使用new()或make()函数分配局部变量，这些变量会被分配在堆上。
	rules = make([]*CompareRule, 0, ruleCount)
	// 定义规则解析零时变量
	var (
		compareVal *CompareRule
		useMod     bool
		useList    bool
		valueCount int
	)
	for {
		// 统计当前rule中比较值的数量，建立CompareRule，创建符合容量的values切片, 避免扩容
		valueCount = 1
		for i = 0; i < len(data); i++ {
			if data[i] == ';' || data[i] == ']' {
				break
			}
			if data[i] == '%' {
				valueCount++
				continue
			}
			if data[i] == ',' {
				valueCount++
				continue
			}
		}
		// 当局部变量被分配在堆上时，函数返回的切片(指针)是安全的。
		// 例如，使用new()或make()函数分配局部变量，这些变量会被分配在堆上。
		compareVal = new(CompareRule)
		compareVal.CompareVals = make([]int, 0, valueCount)
		useMod, useList = false, false
		i, j = 0, 0
		// 优先提取模运算符号规则
		if data[0] == '%' {
			i++
			j++
			useMod = true
			if len(data)-i < 3 { // 模运算符至少需要3个字符，例如：%2>1
				return nil, index, hasCount, ErrRuleParserInvalidType(bytesToString(data[i:]))
			}
			// 提取模运算符的参数
			// 允许负数
			if data[j] == '-' {
				j++
			}
			// 模运算符的参数必须为数字，且不能为0
			if data[j] < '1' || data[j] > '9' {
				return nil, index, hasCount, ErrRuleParserInvalidValue(bytesToString(data[i:j]))
			}
			j++
			for j < len(data) && data[j] >= '0' && data[j] <= '9' {
				j++
			}
			// 允许负数, 不能为0
			if vInt, vErr := strconv.Atoi(bytesToString(data[i:j])); vErr != nil || vInt == 0 {
				return nil, index, hasCount, ErrRuleParserInvalidValue(bytesToString(data[i:j]))
			} else {
				compareVal.CompareVals = append(compareVal.CompareVals, vInt)
			}
			// 裁去左侧已解析的字符
			data = data[j:]
			i, j = 0, 0
		}
		if len(data) < 2 { // 至少需要2个字符，例如：>1
			return nil, index, hasCount, ErrRuleParserInvalidType(bytesToString(data))
		}
		switch bytesToString(data[:2]) {
		case "==":
			// 这里的写法是为了兼容之前的写法
			// `>==` 这样的写法是不合法的
			// 这里需要裁去一个多余的=字符
			data = data[1:]
			i++
		case "!=", ">=", "<=":
			i += 2
		case "![":
			useList = true
			i += 2
		default:
			switch data[0] {
			case '=', '>', '<':
				i++
			case '[':
				useList = true
				i++
			}
		}

		// 通过 i 指针获取比较符号类型
		if i < 1 {
			return nil, index, hasCount, ErrRuleParserInvalidType("cannot empty or invalid type, from: " + bytesToString(data[:min(2, len(data))]))
		}
		// 提取比较符号类型
		switch useMod {
		case true:
			if vType, vOK := ParseCompareType(`%D` + bytesToString(data[0:i])); !vOK {
				return nil, index, hasCount, ErrRuleParserInvalidType(`%d` + bytesToString(data[0:i]))
			} else {
				compareVal.CompareType = vType
			}
		default:
			// 转换data[0:i]字节切片一段为字符串，并转换为比较符号类型
			if vType, vOK := ParseCompareType(bytesToString(data[0:i])); !vOK {
				return nil, index, hasCount, ErrRuleParserInvalidType(bytesToString(data[0:i]))
			} else {
				compareVal.CompareType = vType
			}
		}
		// 裁去左侧已解析的 vType 字符
		data = data[i:]
		i, j = 0, 0
		// 提取比较值 至少一个数字
		if len(data) < 1 {
			return nil, index, hasCount, ErrRuleParserInvalidValue("cannot empty")
		}
		if useList {
			for {
				j = 0
				// 允许负数
				if data[j] == '-' {
					j++
				}
				for j < len(data) && data[j] >= '0' && data[j] <= '9' {
					j++
				}
				if j < len(data) && (data[j] == ',' || data[j] == ']') {
					if j < 1 || bytesToString(data[0:j]) == "-" {
						return nil, index, hasCount, ErrRuleParserInvalidValue("cannot empty")
					}
					if vInt, vErr := strconv.Atoi(bytesToString(data[0:j])); vErr != nil {
						return nil, index, hasCount, ErrRuleParserInvalidValue(bytesToString(data[0:j]))
					} else {
						compareVal.CompareVals = append(compareVal.CompareVals, vInt)
					}
					if data[j] == ']' {
						j++
						data = data[j:]
						j = 0
						break
					} else if data[j] == ',' {
						j++
						data = data[j:]
						j = 0
						continue
					}
				}
				// 此时应为空，或者为 `;`下一条规则的开始
				if len(data[j:]) == 0 || data[j] == ';' {
					if j < 1 || bytesToString(data[0:j]) == "-" {
						return nil, index, hasCount, ErrRuleParserInvalidValue("cannot empty")
					}
					if vInt, vErr := strconv.Atoi(bytesToString(data[0:j])); vErr != nil {
						return nil, index, hasCount, ErrRuleParserInvalidValue(bytesToString(data[0:j]))
					} else {
						compareVal.CompareVals = append(compareVal.CompareVals, vInt)
						// 裁去左侧已解析的字符
						data = data[j:]
						j = 0
					}
					break
				} else {
					return nil, index, hasCount, ErrRuleParserInvalidValue(bytesToString(data))
				}
			}
		} else {
			// 允许负数
			if data[j] == '-' {
				j++
			}
			for j < len(data) && data[j] >= '0' && data[j] <= '9' {
				j++
			}
			// 此时应为空，或者为 `;`下一条规则的开始
			if len(data[j:]) == 0 || (j < len(data) && data[j] == ';') {
				if j < 1 || bytesToString(data[0:j]) == "-" {
					return nil, index, hasCount, ErrRuleParserInvalidValue("cannot empty")
				}
				if vInt, vErr := strconv.Atoi(bytesToString(data[0:j])); vErr != nil {
					return nil, index, hasCount, ErrRuleParserInvalidValue(bytesToString(data[0:j]) + ", error: " + vErr.Error())
				} else {
					compareVal.CompareVals = append(compareVal.CompareVals, vInt)
					// 裁去左侧已解析的字符
					data = data[j:]
					j = 0
				}
			} else {
				return nil, index, hasCount, ErrRuleParserInvalidValue(bytesToString(data))
			}
		}
		// 检查参数
		if useMod && len(compareVal.CompareVals) < 2 {
			return nil, index, hasCount, ErrRuleParserInvalidValue("the number of val must be greater than or equal to 2")
		} else if len(compareVal.CompareVals) < 1 {
			return nil, index, hasCount, ErrRuleParserInvalidValue("cannot empty")
		}
		rules = append(rules, compareVal)
		if len(data) == 0 || data[0] != ';' {
			return rules, index, hasCount, nil
		}
		data = data[1:]
		// 最简单一条规则至少需要2个字符，例如：>1
		if len(data) < 2 {
			return nil, index, hasCount, ErrRuleParserEmpty
		}
	}
}
